#!coding:utf-8
import serial
import urllib
import time
import binascii
from ConfigParser import ConfigParser
import os
# TEMPLATE = u'''玩法:%s    销售日期:%s
# 金额:%s元      开奖时间:%s


# %s

# '''
TEMPLATE = u''' 玩法:%(wanfa)s                  机号:%(jihao)s
 %(barcode2)s
 销售期:%(periodid)s            兑奖截止期:%(validity)s
 销售时间:%(buytime)s     金额:%(tradeamount)s元 
%(nums)s
 开奖时间:%(awardtime)s    
 江西省福利彩票自助销售机，服务热线:%(phonenumber)s
'''

FUSHI_TEMPLATE = u'''红复:%s
蓝复:%s
'''

indexmap = {0:'A ',1:'B ',2:'C ',3:'D ',4:'E '}
shengxiao_dict = {'1':u'鼠','2':u'牛','3':u'虎','4':u'兔','5':u'龙','6':u'蛇','7':u'马','8':u'羊','9':u'猴','10':u'鸡','11':u'狗','12':u'猪'}

SETLEFT = "1b6100".decode('hex')  #设置打印居中,1B 61 n,n=0左对齐，n=1居中,n=2右对齐
SETCENTER = "1b6101".decode('hex')

#CUTPAPER = "0c1b4aff1b4a321b691b40".decode('hex')  #找黑标切纸
CUTPAPER = '1D28460400020000001d5600' #切纸

def compact(title,balls,width=13,leftpadding=7,margin=1):
    for index,r in enumerate(balls):
        if (index+1) % width ==0: #每行8个数字
            title += "\n" + ' ' * leftpadding
        title += r+' ' * margin
    
    return title+"\n"

def ssq(numdata):
    numstr = []
    numstr.append('1b4501'.decode('hex'))
    for index,ndata in enumerate(numdata['num']):
        reds = (ndata.split('|')[0]).split(',')
        blues = ndata.split('|')[-1].split(',')

        if numdata['fs'] == 'danshi':
            reds.extend(blues)
            numstr.append(" "+indexmap[index]+u"{0}    {1}    {2}    {3}    {4}    {5} |  {6}".format(*reds)+"  (%s)"%numdata['beishu'])
        elif numdata['fs'] == 'fushi':
            result = '1b4501'.decode('hex') #字体加粗指令
            result += '\n'
            result += compact(u" 红复: ",reds)+compact(u" 蓝复: ",blues) + u" 倍数: %s\n"%numdata['beishu'] #复式只能有一注
            result += '1b4500'.decode('hex')
            result += '\n'
            return result
        elif numdata['fs'] == 'dantuo':
            danmas = ndata.split('$')[0].split(',')
            tuomas = ndata.split('$')[1].split('|')[0].split(',')
            blues  = ndata.split('|')[1].split(',')
            result = '1b4501'.decode('hex') #字体加粗指令
            result += '\n'
            result += compact(u" 胆码: ",danmas) + compact(u" 拖码: ",tuomas) + compact(u" 蓝球: ",blues) +u" 倍数: %s\n"%numdata['beishu'] #胆托只能有一注
            result += '1b4500'.decode('hex')
            return result
    numstr.append('1b4500'.decode('hex'))
    return '\n'.join(numstr)+'\n'*(5-len(numstr))


ssc_dict = {'1':u'一星单选','2':u'二星单选','3':u'三星单选','4':u'四星单选','5':u'五星单选','10':u'二星组选','11':u'大小单双',
            '12':u'五星通选','15':u'三星组三','16':u'三星组六'}
def ssc(numdata):
    '''时时彩彩票打印格式化'''
    result = '1b4501'.decode('hex') #字体加粗指令
    result += '\n'
    desc = ssc_dict.get(numdata['wanfa'])
    if numdata['fs'] == '1': #单式
        index = 0
        for ndata in numdata['num']:
            result += '%s%s      (%s)\n'%(u' %s(单式): '%desc, ndata,numdata['beishu'])
            index += 1
        result += '\n'*(4-index)
    elif numdata['fs'] == '2': #复式
        balls = numdata['num'][0]
        result += '%s%s      (%s)\n'%(u' %s(复式): '%desc, balls,numdata['beishu'])
        result += '\n'
    else: #其它玩法
        result += '%s%s      (%s)\n'%(u' %s: '%desc,numdata['num'][0],numdata['beishu'])
        result += '\n'*3
    result += '1b4500'.decode('hex') #取消加粗
    
    return result
    
def sevencolor(numdata): #七乐彩
    '''七乐彩彩票打印格式化'''
    numstr = []
    numstr.append('1b4501'.decode('hex'))
    for index,ndata in enumerate(numdata['num']):
        reds = ndata.split(',')

        if numdata['fs'] == 'danshi':
            numstr.append(" "+indexmap[index]+u"{0}    {1}    {2}    {3}    {4}    {5}    {6}".format(*reds)+"  (%s)"%numdata['beishu'])
        elif numdata['fs'] == 'fushi':
            result = '1b4501'.decode('hex') #字体加粗指令
            result += '\n'
            result += compact(u" 复选: ",reds) + u" 倍数: %s\n"%numdata['beishu'] #复式只能有一注
            result += '1b4500'.decode('hex')
            result += '\n'
            return result
        elif numdata['fs'] == 'dantuo':
            danmas = ndata.split('$')[0].split(',')
            tuomas = ndata.split('$')[1].split(',')
            result = '1b4501'.decode('hex') #字体加粗指令
            result += '\n'
            result += compact(u" 胆码: ",danmas) + compact(u" 拖码: ",tuomas) + u" 倍数: %s\n"%numdata['beishu'] #胆托只能有一注
            result += '1b4500'.decode('hex')
            return result
    numstr.append('1b4500'.decode('hex'))
    return '\n'.join(numstr)+'\n'*(5-len(numstr))


threeD_dict={'1':u'单选三','2':u'组选三(包号)','3':u'组选六(包号)'}
def threeD(numdata): #福彩3D
    '''福彩3D彩票打印格式化'''
    result = '1b4501'.decode('hex') #字体加粗指令
    result += '\n'
    desc = threeD_dict.get(numdata['wanfa'])
    if numdata['fs'] == '1': #单式
        index = 0
        for ndata in numdata['num']:
            index += 1
            result += '%s%s      (%s)\n'%(u' %s(单式): '%desc, ndata,numdata['beishu'])
        result += '\n'*(4-index)
    elif numdata['fs'] == '2': #复式
        balls = numdata['num'][0]
        result += '%s%s      (%s)\n'%(u' %s(复式): '%desc, balls,numdata['beishu'])
        result += '\n'
    else: #其它玩法
        result += '%s%s      (%s)\n'%(u' %s: '%desc,numdata['num'][0],numdata['beishu'])
        result += '\n'*3
    
    result += '1b4500'.decode('hex') #取消加粗
    return result

def fifteenfive(numdata): #十五选五
    '''十五选五彩票打印格式化'''
    numstr = []
    numstr.append('1b4501'.decode('hex'))
    for index,ndata in enumerate(numdata['num']):
        reds = ndata.split(',')

        if numdata['fs'] == 'danshi':
            numstr.append(" "+indexmap[index]+u"{0}    {1}    {2}    {3}    {4}".format(*reds)+"  (%s)"%numdata['beishu'])
        elif numdata['fs'] == 'fushi':
            result = '1b4501'.decode('hex') #字体加粗指令
            result += '\n'
            result += compact(u" 复选: ",reds) + u" 倍数: %s\n"%numdata['beishu'] #复式只能有一注
            result += '1b4500'.decode('hex')
            result += '\n'
            return result
        elif numdata['fs'] == 'dantuo':
            danmas = ndata.split('$')[0].split(',')
            tuomas = ndata.split('$')[1].split(',')
            result = '1b4501'.decode('hex') #字体加粗指令
            result += '\n'
            result += compact(u" 胆码: ",danmas) + compact(u" 拖码: ",tuomas) + u" 倍数: %s\n"%numdata['beishu'] #胆托只能有一注
            result += '1b4500'.decode('hex')
            result += '\n'
            return result
    numstr.append('1b4500'.decode('hex'))
    return '\n'.join(numstr)+'\n'*(5-len(numstr))

def six_plus_one(numdata): #东方6+1
    '''十五选五彩票打印格式化'''
    numstr = []
    numstr.append('1b4501'.decode('hex'))
    for index,ndata in enumerate(numdata['num']):
        reds = (ndata.split('|')[0]).split(',')
        shengxiaos = ndata.split('|')[-1].split(',')
        shengxiaos_desc = [shengxiao_dict.get(sx) for sx in shengxiaos]
        
        if numdata['fs'] == 'danshi':
            reds.extend(shengxiaos_desc)
            numstr.append(" "+indexmap[index]+u"{0}  {1}  {2}  {3}  {4}  {5} |  {6}".format(*reds)+"  (%s)"%numdata['beishu'])
        elif numdata['fs'] == 'fushi':
            result = '1b4501'.decode('hex') #字体加粗指令
            result += '\n'
            result += compact(u" 第一位: ",list(reds[0])) + compact(u" 第二位: ",list(reds[1])) + compact(u" 第三位: ",list(reds[2])) + compact(u" 第四位: ",list(reds[3]))\
                +compact(u" 第五位: ",list(reds[4])) + compact(u" 第六位: ",list(reds[5])) + compact(u" 生肖: ",shengxiaos_desc) + u" 倍数: %s"%numdata['beishu'] #复式只能有一注
            result += '1b4500'.decode('hex')
            return result,'fs'

    numstr.append('1b4500'.decode('hex'))            
    return '\n'.join(numstr)+'\n'*(5-len(numstr))

def test_pprint(serial_port='com4'):
    try:
        s = serial.Serial(serial_port,baudrate=9600)
        s.write(SETCENTER)
#        s.write('1F1B1F8004050644'.decode('hex')) #打开黑标
#        s.write('1F1B1F820405062800'.decode('hex')) #设置黑标纸长度上限100mm
#        s.write('1F1B1F810405062003'.decode('hex')) #设置黑标纸宽度上限5mm
#        s.write('1d541d2846040001002801'.decode('hex')) #设置打印位置相对黑标的偏移为37mm TODO:
        s.write('below is a test for tiaoma print.\n')
        #-------- add terminal number in test print start ----------
        conf = load_config(conf='yeepaydata.conf')
        s.write(binascii.b2a_hex((u'终端号: %s\n'%conf['terminal_number']).encode('gb2312')).decode('hex'))
        #-------- add terminal number in test print end ----------
        s.write('1d6866'.decode('hex'))
        s.write('0a1b4a010a'.decode('hex'))
        s.write(SETCENTER)
        s.write(("1d6b04333435393832333435000A").decode('hex'))
#        s.write('1d541d284604000200d800'.decode('hex')) #设置切刀位置相对黑标的偏移为27mm
        s.write('1d5601'.decode('hex')) #切刀命令
#        s.write(CUTPAPER)
    except Exception as e:
        print "an exception occured in test_pprint:%s"%e
        return False
    finally:
        s.close()

def load_config(conf='lottery.conf'):
    c = ConfigParser()
    try:
        CONF_PATH=os.path.join(os.path.dirname(os.path.dirname(__file__)),conf)
        c.read(os.path.join(os.path.abspath('.'),CONF_PATH))
        return dict(c.items('default'))
    except Exception as e:
        print "can not read config in printer : lottery.conf %s"%e


def pprint(lottery_type,data,serial_port='com4'):
    '''
    wanfa  #玩法
    jihao  #机号
    periodid  #销售期
    validity #有效期
    buytime  #销售时间
    trade_amount  #金额
    awardtime #开奖日期
    phonenumber #电话
    '''
    conf = load_config()
    URL = conf['url'][:-1] if conf['url'].endswith('/') else conf['url']
#    from main import URL
    sd_batchid = data['sd_batchid']
    result = urllib.urlopen('%s/%s/%s'%(URL,'getsdresult',sd_batchid))
    sd_result = result.read().strip()
    times = 0
    while sd_result == '0':
        times += 1
        time.sleep(0.01)
        result = urllib.urlopen('%s/%s/%s'%(URL,'getsdresult',sd_batchid))
        sd_result = result.read().strip()
        if times>1000:
            return False
        
    if sd_result != '2':
        return False
            
    tikets = []
    special_cut = False  #不找黑标切纸
    for ndata in data['num_list']:
        if lottery_type == '01':
            numstr = ssq(ndata)
        elif lottery_type == '20':
            numstr = ssc(ndata)
        elif lottery_type == '07':
            numstr = sevencolor(ndata)
        elif lottery_type == '05':
            numstr = threeD(ndata)
        elif lottery_type == '15':
            numstr = fifteenfive(ndata)
        elif lottery_type == '06':
            res = six_plus_one(ndata)
            if type(res) is tuple:
                numstr = res[0]
                special_cut = True
            else:
                numstr = res
#            numstr = ssc_two(ndata)
            
        data.update(tradeamount=ndata['tradeamount'],nums=numstr)
        barcode2 = '%s' % (int(ndata['batchid'])+123)  #对显示在票面上的数据进行混淆
        barcode2=barcode2[0:4]+"-"+barcode2[4:8]+"-"+barcode2[8:]
        data.update(barcode2=barcode2)
        balls_content = binascii.b2a_hex((TEMPLATE % data).encode('gb2312'))
        tikets.append({'tiaoma':gen_tiaoma(ndata['batchid']),'tiaoma_desc':ndata['batchid'],'balls': balls_content})
#
    try:
        s = serial.Serial(serial_port,baudrate=9600)
        for p in tikets:
            _print_lottery(s,p,serial_port,special_cut=special_cut)
        return True
    except Exception as e:
        print "an exception occured in pprint:%s"%e
        return False
    finally:
        s.close()
    # for t in tikets:
    #     for c in t['balls'].encode('gbk').split('\n'):

    # return True

def _print_lottery(s,ticket,serial_port,times=0,special_cut=False):
    try:
        s.write(SETLEFT)
        s.write(ticket['balls'].decode('hex'))
        s.write('0a1b4a010a'.decode('hex'))
        s.write(SETCENTER)
        s.write('1d6866'.decode('hex')) #设置条码宽度
        s.write(ticket['tiaoma'])
        if special_cut:
            s.write('1b4aff1b4a101b69'.decode('hex'))  #半切
        else:
            s.write('1d5601'.decode('hex'))  #半切
        return
    except:
        print 'print error,please check paper'  #TODO:做弹窗提示
        time.sleep(60)
        times += 1
        while times<10:
            test_pprint(serial_port)
            _print_lottery(s,ticket,times)
    
def gen_tiaoma11(barcode):
    #int(time.time()*1000000)
    # 1d 6b 49 07 7b 43 0c 22 38 4e 5a
    # gs k  73 18 123 67 13 46 11 47 98 38 12 67
    hexcode = []
    index = 0
    while index+2 <=len(barcode):
        hexcode.append(hex(int(barcode[index:index+2]))[-2:].replace('x','0')) #获取最后两位，x字符用0替换
        index = index+2
    tiaomalen = hex(len(barcode)/2+2)[-2:].replace('x','0')

    return barcode +"\n"+("1d6b49"+tiaomalen+"7b43"+"".join(hexcode)).decode('hex')  #条码

def gen_tiaoma(barcode):
    tiaoma_hex ='1d77021d6b04'+binascii.b2a_hex(barcode)+'000a'
    return tiaoma_hex.decode('hex')

def init_printer(serial_port='com4'):
    s = None
    try:
        s = serial.Serial(serial_port,baudrate=9600)
        s.write('1F1B1F8004050644'.decode('hex')) #打开黑标
        s.write('1F1B1F820405062800'.decode('hex')) #设置黑标纸长度上限100mm
        s.write('1F1B1F810405062003'.decode('hex')) #设置黑标纸宽度上限5mm
        s.write('1d541d2846040001002801'.decode('hex')) #设置打印位置相对黑标的偏移为37mm
        s.write('1d541d284604000200d800'.decode('hex')) #设置切刀位置相对黑标的偏移为27mm
    except:
        print 'initialize printer failed.'
    finally:
        if s:
            s.close()

if __name__ == '__main__':
    
    # ballformat = u"  {0}   {1}   {2}   {3}   {4}   {5}   {6}  | {7} (1)"

    # numlist = [{2:['01','01','01','01','01','01','01']},{8:['01','01','01','01','01','01','01','02','03'}]

    # lottery_type = 1
    # saledate = "20120820"

    # enddate = "20120829"
    # barcode = "7646562883"
    
    
    ##======================= 时时彩打印测试 ===========================
#    data={'awardtime': '2012-10-23 14:20:00', 'wanfa': u'\u65f6\u65f6\u5f69', 'buytime': '2012-10-23 14:17:56', 'jihao': u'xxx', 'periodid': u'1023032', 'phonenumber': '400-088-0932', 'num_list': [{'beishu': 1, 'fs': u'1', 'wanfa': u'11', 'batchid': '135106334134', 'num': [u'\u5927,\u5927', u'\u5355,\u5355', u'\u5927,\u5c0f', u'\u5355,\u5927', u'\u53cc,\u5927'], 'tradeamount': 10}, {'beishu': 1, 'fs': u'1', 'wanfa': u'11', 'batchid': '135106334135', 'num': [u'\u53cc,\u5c0f', u'\u5c0f,\u53cc'], 'tradeamount': 4}], 'validity': u'1023032', 'msg': u'\u51fa\u7968\u6210\u529f,\u6253\u5370\u5f69\u7968'}
#    pprint('20',data)
    #======================= 七乐彩打印测试 ==============================
    
#    data={'awardtime': '2012-10-24 20:45:00', 'wanfa': u'\u4e03\u4e50\u5f69', 'buytime': '2012-10-23 14:32:49', 'jihao': u'xxx', 'periodid': u'2012125', 'phonenumber': '400-088-0932', 'num_list': [{'batchid': '135106154485', 'beishu': 2, 'num': [u'01,02,03,04,05,06$11,12,13'], 'tradeamount': 12, 'fs': 'dantuo'}, {'batchid': '135106154486', 'beishu': 2, 'num': [u'02,12,14,22,23,24$15,16,17'], 'tradeamount': 12, 'fs': 'dantuo'}], 'validity': u'2012125', 'msg': u'\u51fa\u7968\u6210\u529f,\u6253\u5370\u5f69\u7968'}
#    pprint('07',data)
    #======================= 福彩3D打印测试 ============================
    data={'awardtime': '2012-10-25 20:30:00', 'wanfa': u'\u798f\u5f693D', 'buytime': '2012-10-25 15:06:43', 'jihao': u'xxx2', 'periodid': u'2012292', 'phonenumber': '400-088-0932', 'num_list': [{'beishu': 1, 'fs': u'1', 'wanfa': u'2', 'batchid': '135123207414', 'num': [u'0,1,1'], 'tradeamount': 2}], 'validity': u'2012292', 'msg': u'\u51fa\u7968\u6210\u529f,\u6253\u5370\u5f69\u7968'}
    pprint('05',data)
    #======================= 15选5打印测试 =============================
#    data={'awardtime': '2012-10-23 20:30:00', 'wanfa': u'15\u90095', 'buytime': '2012-10-23 14:51:26', 'jihao': u'xxx', 'periodid': u'2012290', 'phonenumber': '400-088-0932', 'num_list': [{'batchid': '135105573265', 'beishu': 1, 'num': [u'01,02,03,04$08,09,14'], 'tradeamount': 6, 'fs': 'dantuo'}, {'batchid': '135105573266', 'beishu': 1, 'num': [u'02,07,12,13$01,03,04'], 'tradeamount': 6, 'fs': 'dantuo'}], 'validity': u'2012290', 'msg': u'\u51fa\u7968\u6210\u529f,\u6253\u5370\u5f69\u7968'}
#    pprint('15',data)
    #======================= 东方6+1打印测试 ===========================
#    data={'awardtime': '2012-10-24 20:45:00', 'wanfa': u'\u4e1c\u65b96+1', 'buytime': '2012-10-23 14:54:53', 'jihao': u'xxx', 'periodid': u'2012125', 'phonenumber': '400-088-0932', 'num_list': [{'batchid': '135103995017', 'beishu': 1, 'num': [u'01,12,23,34,45,56|1,6'], 'tradeamount': 256, 'fs': 'fushi'}, {'batchid': '135103995018', 'beishu': 1, 'num': [u'7,4,8,6,2,1|8', u'2,4,8,1,5,7|6', u'1,7,5,4,6,9|3', u'8,7,5,1,2,9|12', u'3,6,2,1,8,7|6'], 'tradeamount': 10, 'fs': 'danshi'}, {'batchid': '135103995019', 'beishu': 1, 'num': [u'7,5,8,6,2,4|4', u'9,8,5,6,3,4|10'], 'tradeamount': 4, 'fs': 'danshi'}], 'validity': u'2012125', 'msg': u'\u51fa\u7968\u6210\u529f,\u6253\u5370\u5f69\u7968'}
#    pprint('06',data)
    # print ssq({
    #         'batchid': '134730344282',
    #         'num': ["11,05,14,15,10,03|12","11,05,14,15,10,03|12","11,05,14,15,10,03|12","11,05,14,15,10,03|12","11,05,14,15,10,03|12"],
    #         'tradeamount': 14,
    #         'fs': 'danshi'
    #     })
        
    
    #============== 双色球打印测试 =======================
#    data={'awardtime': '2012-10-23 20:45:00', 'wanfa': u'\u53cc\u8272\u7403', 'buytime': '2012-10-23 11:46:02', 'jihao': u'xxx', 'periodid': u'2012125', 'phonenumber': '400-088-0932', 'num_list': [{'batchid': '135104719265', 'beishu': 2, 'num': [u'01,02,03,04,05,06,17,18|01'], 'tradeamount': 112, 'fs': 'fushi'}, {'batchid': '135104719266', 'beishu': 2, 'num': [u'08,03,07,23,18,16|14', u'11,25,21,07,26,03|15', u'06,05,27,23,19,20|09', u'14,03,21,12,02,23|05', u'30,28,11,16,05,26|06'], 'tradeamount': 20, 'fs': 'danshi'}, {'batchid': '135104719267', 'beishu': 2, 'num': [u'26,15,19,23,02,03|14', u'16,17,08,12,02,26|13'], 'tradeamount': 8, 'fs': 'danshi'}], 'validity': u'2012125', 'msg': u'\u51fa\u7968\u6210\u529f,\u6253\u5370\u5f69\u7968'}
#    data = {'awardtime': '2012-10-23 20:45:00', 'wanfa': u'\u53cc\u8272\u7403', 'buytime': '2012-10-23 11:51:33', 'jihao': u'xxx', 'periodid': u'2012125', 'phonenumber': '400-088-0932', 'num_list': [{'batchid': '135099434908', 'beishu': 1, 'num': [u'01,02,04,05,14$10,11,12,13|01,02'], 'tradeamount': 16, 'fs': 'dantuo'}], 'validity': u'2012125', 'msg': u'\u51fa\u7968\u6210\u529f,\u6253\u5370\u5f69\u7968'}
#    pprint('01',data)
    
